TOC »
Cross Development
Since CHICKEN generates C code, it is relatively easy to create programs and libraries for a different architecture than the one the compiler is executing on, a process commonly called cross compiling. Basically you can simply compile Scheme code to C and then invoke your target-specific cross compiler. To automate the process of invoking the correct C compiler with the correct settings and to simplify the use of extensions, CHICKEN can be built in a special "cross-compilation" mode.
Note: in the following text we refer to the "target" as being the platform on which the software is intended to run in the end. We use the term "host" as the system that builds this software. Others use a different nomenclature or switch the meaning of the words.
Preparations
Make sure you have a cross-toolchain in your PATH. In this example, a Linux system is used to generate binaries for an ARM based embedded system.
Building the target libraries
First you need a version of the runtime system (libchicken), compiled for the target system. Obtain and unpack a tarball of the CHICKEN sources, or check out the code from the official code repository, then build the libraries and necessary development files:
make ARCH= \
PREFIX=/usr \
PLATFORM=linux \
HOSTSYSTEM=arm-none-linux-gnueabi \
DESTDIR=$HOME/target \
TARGET_FEATURES="-no-feature x86 -feature arm" \
installThis will build CHICKEN and install it in ~/target, which we use as a temporary place to store the target files. A few things to note:
- ARCH is empty, since we don't want the build process to detect the architecture (since the target-architecture is likely to be different). If you know the right string to represent target architecture, you can set ARCH with that value. This string is passed to the -arch compiler and linker option for ios and sometimes conditionally checked in platform-specific makefiles)
- PREFIX gives the prefix on the target system, under which the libraries will finally be installed. In this case it will be /usr/lib.
- PLATFORM determines the target platform. It must be one of the officially supported platforms CHICKEN runs on. Note that it actually refer to the extension of a dedicated Makefile (`Makefile.linux` in our case).
- HOSTSYSTEM is an identifier for the target system and will be used as the name prefix of the cross C compiler (in this case arm-none-linux-gnueabi-gcc). If your cross compiler does not follow this convention, pass C_COMPILER and LIBRARIAN to the make(1) invocation, with the names of the C compiler and ar(1) tool, respectively.
- DESTDIR holds the directory where the compiled library files will temporarily be installed into.
- TARGET_FEATURES contains extra options to be passed to the target-specific Scheme translator; in this case we disable and enable features so that code like the following will do the right thing when cross-compiled:
(cond-expand
(x86 <do this ...>)
...)- If you obtained the sources from a source-code repository and not from an official release tarball, you will need a chicken executable to compile the Scheme sources of the runtime system. In this case pass yet another variable to the make(1) invocation: CHICKEN=<where the "chicken" executable is>.
- You can also put all those variables into a file, say config.mk and run make CONFIG=config.mk.
You should now have these files on ~/target:
|-- bin
| |-- chicken
| |-- chicken-bug
| |-- chicken-install
| |-- chicken-profile
| |-- chicken-status
| |-- chicken-uninstall
| |-- csc
| `-- csi
|-- include
| |-- chicken-config.h
| `-- chicken.h
|-- lib
| |-- chicken
| | `-- 9
| | :
| |
| |-- libchicken.a
| |-- libchicken.so -> libchicken.so.9
| `-- libchicken.so.9
`-- share
|-- chicken
| |-- doc
: ; :
| |
| `-- setup.defaults
`-- man
`-- man1
:You should now transfer ~/target/usr/lib to the target system, and place its contents in /usr/lib. You may want to omit the static library libchicken.a if the target memory is limited.
Building the "cross chicken"
Next, we will build another chicken, one that uses the cross C compiler to generate target-specific code that uses the target-specific runtime library we have just built.
Again, unpack a CHICKEN release tarball or a source tree and run make(1) once again:
make PLATFORM=linux \
PREFIX=$HOME/cross-chicken \
TARGETSYSTEM=arm-none-linux-gnueabi \
PROGRAM_PREFIX=arm- \
TARGET_PREFIX=$HOME/target/usr \
TARGET_RUN_PREFIX=/usr \
install- PREFIX gives the place where the "cross chicken" should be installed into. It is recommended not to install into a standard location (like /usr/local or $HOME) - some files will conflict with a normal CHICKEN installation.
- TARGETSYSTEM gives the name-prefix of the cross C compiler and other tools (C++ compiler, librarian (ar) and ressource compiler (for windows)).
- PROGRAM_PREFIX determines the name-prefix of the CHICKEN tools to be created.
- TARGET_PREFIX specifies where the target-specific files (libraries and headers) are located. This is the location where we installed the runtime system into.
- TARGET_RUN_PREFIX holds the PREFIX that will be effective at runtime (so libchicken.so will be found in $TARGET_RUN_PREFIX/lib).
- Make sure to use the same version of the CHICKEN sources for the target and the cross build.
- If you build the cross chicken from repository sources, the same note about the CHICKEN variable applies as given above.
In ~/cross-chicken, you should find the following:
|-- bin | |-- arm-chicken | |-- arm-chicken-install | |-- arm-chicken-profile | |-- arm-chicken-status | |-- arm-chicken-uninstall | |-- arm-csc | `-- arm-csi |-- include | |-- chicken-config.h | `-- chicken.h |-- lib | |-- chicken | | `-- 9 | | : | | | |-- libchicken.a | |-- libchicken